# frozen_string_literal: true

RSpec.shared_examples 'username and email pair is generated by Gitlab::Utils::UsernameAndEmailGenerator' do
  let(:randomhex) { 'randomhex' }

  it 'check email domain' do
    expect(subject.email).to end_with("@#{email_domain}")
  end

  it 'contains SecureRandom part' do
    allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)

    expect(subject.username).to include("_#{randomhex}")
    expect(subject.email).to include("_#{randomhex}@")
  end

  it 'email name is the same as username' do
    expect(subject.email).to include("#{subject.username}@")
  end

  context 'when conflicts' do
    let(:reserved_username) { "#{username_prefix}_#{randomhex}" }
    let(:reserved_email) { "#{reserved_username}@#{email_domain}" }

    shared_examples 'uniquifies username and email' do
      it 'uniquifies username and email' do
        expect(subject.username).to eq("#{reserved_username}1")
        expect(subject.email).to include("#{subject.username}@")
      end
    end

    context 'when username is reserved' do
      context 'when username is reserved by user' do
        before do
          create(:user, username: reserved_username)
          allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with top-level group namespace' do
        before do
          create(:group, path: reserved_username)
          allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with top-level group namespace that includes upcased characters' do
        before do
          create(:group, path: reserved_username.upcase)
          allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
        end

        include_examples 'uniquifies username and email'
      end
    end

    context 'when email is reserved' do
      context 'when it conflicts with confirmed primary email' do
        before do
          create(:user, email: reserved_email)
          allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with unconfirmed primary email' do
        before do
          create(:user, :unconfirmed, email: reserved_email)
          allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with confirmed secondary email' do
        before do
          create(:email, :confirmed, email: reserved_email)
          allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
        end

        include_examples 'uniquifies username and email'
      end
    end

    context 'when email and username is reserved' do
      before do
        create(:user, email: reserved_email)
        create(:user, username: "#{reserved_username}1")
        allow(SecureRandom).to receive(:hex).at_least(:once).and_return(randomhex)
      end

      it 'uniquifies username and email' do
        expect(subject.username).to eq("#{reserved_username}2")

        expect(subject.email).to include("#{subject.username}@")
      end
    end
  end
end
